package com.dwd.user.service.impl;

import com.dwd.basic.constant.PetLoginConstant;
import com.dwd.basic.constant.VerificationConstant;
import com.dwd.basic.exception.CustomException;
import com.dwd.basic.service.impl.BaseServiceImpl;
import com.dwd.basic.utils.MD5Utils;
import com.dwd.basic.utils.StrUtils;
import com.dwd.org.pojo.Employee;
import com.dwd.user.mapper.LoginInfoMapper;
import com.dwd.user.mapper.UserMapper;
import com.dwd.user.pojo.LoginInfo;
import com.dwd.user.pojo.User;
import com.dwd.user.pojo.dto.LoginInfoDto;
import com.dwd.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * @Description: TODO
 * @Author 汶狄
 * @Date 2021/1/16 12:37
 * @Version 1.0
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 校验手机号码是否存在
     *
     * @param phone
     * @throws CustomException
     */
    @Override
    public void checkPhone(String phone) throws CustomException {
        if (StringUtils.isEmpty(phone)) {
            throw new CustomException("手机不能为空");
        }

        //手机号码是否正确
        String Regex = "(?:(?:(?:13[0-9])|(?:14[57])|(?:15[0-35-9])|(?:19[0-35-9])|(?:17[36-8])|(?:18[0-9]))\\d{8})|(?:170[057-9]\\d{7})";
        if (!phone.matches(Regex)) {
            throw new CustomException("请输入正确的手机号码");
        }

        User user1 = userMapper.queryUserByPhone(phone);
        if (user1 != null) {
            throw new CustomException("用户已经注册了");
        }
    }

    /**
     * 扩展登陆
     *
     * @param username
     * @param password
     * @return
     * @throws CustomException
     */
    @Override
    public Employee login(String username, String password) throws CustomException {
        Employee loginUser = userMapper.queryEmpByUsername(username);
        if (loginUser != null) {
            if (loginUser.getPassword().equals(password)) {
                return loginUser;
            } else {
                throw new CustomException("密码错误");
            }
        } else {
            throw new CustomException("用户不存在");
        }
    }

    /**
     * 手机注册
     *
     * @param loginInfoDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(LoginInfoDto loginInfoDto) throws CustomException {
        //校验
        checkData(loginInfoDto);
        //创建logininfo对象
        LoginInfo loginInfo = createLoginInfo(loginInfoDto);
        //保存到logininfo表中
        loginInfoMapper.save(loginInfo);
        //创建user对象
        User user = createUser(loginInfo);
        //保存到user表中
        userMapper.save(user);

    }

    /**
     * 邮箱注册
     *
     * @param loginInfoDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void emailRegister(LoginInfoDto loginInfoDto) throws CustomException {
        //校验数据
        checkEmailData(loginInfoDto);

        //创建logininfo对象
        LoginInfo loginInfo = createLoginInfoEmai(loginInfoDto);
        //保存到logininfo表中
        loginInfoMapper.save(loginInfo);
        //创建user对象
        User user = createUserEmail(loginInfo);
        //保存到user表中
        userMapper.save(user);
    }

    /**
     * 邮箱注册user
     *
     * @param loginInfo
     * @return
     */
    private User createUserEmail(LoginInfo loginInfo) {
        User user = new User();
        //把loginInfoDto里面的属性给user拷贝
        BeanUtils.copyProperties(loginInfo, user);
        //设置状态
        user.setState(PetLoginConstant.HOME);
        //设置loginInfo
        user.setLoginInfo(loginInfo);
        return user;
    }

    /**
     * 邮箱注册logininfo
     *
     * @param loginInfoDto
     * @return
     */
    private LoginInfo createLoginInfoEmai(LoginInfoDto loginInfoDto) {
        LoginInfo loginInfo = new LoginInfo();
        //设置电话
        loginInfo.setEmail(loginInfoDto.getEmail());
        //设置盐值
        loginInfo.setSalt(StrUtils.getComplexRandomString(10));
        //设置密码md5盐值加密
        loginInfo.setPassword(MD5Utils.encrypByMd5(loginInfoDto.getPassword() + loginInfo.getSalt()));
        //设置普通用户
        loginInfo.setType(loginInfoDto.getType());
        return loginInfo;
    }

    /**
     * 校验邮箱数据
     *
     * @param loginInfoDto
     */
    private void checkEmailData(LoginInfoDto loginInfoDto) throws CustomException {
        //邮箱是否为空
        if (StringUtils.isEmpty(loginInfoDto.getEmail())) {
            throw new CustomException("邮箱不能为空");
        }
        //邮箱是否合法
        String regex = "^[a-z0-9]+([._\\\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$";
        if (!loginInfoDto.getEmail().matches(regex)) {
            throw new CustomException("邮箱不合法");
        }
        //邮箱是否存在
        User user1 = userMapper.queryUserByEmail(loginInfoDto.getEmail());
        if (user1 != null) {
            throw new CustomException("邮箱已经注册了");
        }
        String value = (String) redisTemplate.opsForValue().get(loginInfoDto.getEmail() + ":" + VerificationConstant.USER_EMAIL);
        //校验其他数据
        check(loginInfoDto, value);
    }

    /**
     * 手机注册 创建user
     *
     * @param loginInfo
     * @return
     */
    private User createUser(LoginInfo loginInfo) {
        User user = new User();
        //把loginInfoDto里面的属性给user拷贝
        BeanUtils.copyProperties(loginInfo, user);
        //设置状态
        user.setState(PetLoginConstant.HOME);
        //设置loginInfo
        user.setLoginInfo(loginInfo);
        return user;
    }

    /**
     * 手机注册 创建logininfo 存入logininfo的对象，给对象赋值
     *
     * @param loginInfoDto
     * @return
     */
    private LoginInfo createLoginInfo(LoginInfoDto loginInfoDto) {
        LoginInfo loginInfo = new LoginInfo();
        //设置电话
        loginInfo.setPhone(loginInfoDto.getPhone());
        //设置盐值
        loginInfo.setSalt(StrUtils.getComplexRandomString(10));
        //设置密码md5盐值加密
        loginInfo.setPassword(MD5Utils.encrypByMd5(loginInfoDto.getPassword() + loginInfo.getSalt()));
        //设置普通用户
        loginInfo.setType(loginInfoDto.getType());
        return loginInfo;
    }

    /**
     * 校验手机注册数据
     *
     * @param loginInfoDto
     */
    private void checkData(LoginInfoDto loginInfoDto) throws CustomException {
        //手机不能为空
        checkPhone(loginInfoDto.getPhone());
        String value = (String) redisTemplate.opsForValue().get(loginInfoDto.getPhone() + ":" + VerificationConstant.USER_REG);
        //校验其他数据
        check(loginInfoDto,value);
    }

    /**
     * 抽取公共校验
     *
     * @param loginInfoDto
     * @param value
     * @throws CustomException
     */
    public void check(LoginInfoDto loginInfoDto, String value) throws CustomException {
        //验证码不能为空
        if (StringUtils.isEmpty(loginInfoDto.getCode())) {
            throw new CustomException("验证码不能为空");
        }
        //验证码是否过期
        if (StringUtils.isEmpty(value)) {
            throw new CustomException("验证码已经过期，请重新获取");
        }
        //验证码是否正确
        if (!loginInfoDto.getCode().toUpperCase().equals(value.split(":")[0].toUpperCase())) {
            throw new CustomException("验证码不正确");
        }
        //密码不能为空
        if (StringUtils.isEmpty(loginInfoDto.getPassword())) {
            throw new CustomException("密码不能为空");
        }
        //密码长度为6到20位,必须包含字母和数字，字母区分大小写
        String regex = "^(?=.*[0-9])(?=.*[a-zA-Z])(.{6,20})$";
        if (!loginInfoDto.getPassword().matches(regex)) {
            throw new CustomException("密码长度为6到20位,必须包含字母和数字，字母区分大小写");
        }
        //确认密码不能为空
        if (StringUtils.isEmpty(loginInfoDto.getConfirmpassword())) {
            throw new CustomException("确认密码不能为空");
        }
        //密码与确认密码一致
        if (!loginInfoDto.getPassword().equals(loginInfoDto.getConfirmpassword())) {
            throw new CustomException("密码不一致");
        }
    }
}
